package com.xpxrule.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.xpxrule.dataobject.biz.model.ReturnResponse;
import com.xpxrule.dataobject.dao.ConstantItem;
import com.xpxrule.dataobject.req.ConstantItemQueryReq;
import com.xpxrule.dataobject.vo.ConstantItemVo;
import com.xpxrule.mapper.ConstantItemMapper;
import com.xpxrule.service.ConstantItemService;
import com.xpxrule.util.ModelConvertUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ConstantItemServiceImpl implements ConstantItemService {
    @Autowired
    private ConstantItemMapper constantItemMapper;
    @Override
    public ReturnResponse<Integer> insert(ConstantItemVo vo) {
        boolean isExist = verifyDbUnique(vo);
        if (!isExist) {
            return ReturnResponse.fail("The unique verification failed. The new data already exists in the database.");
        }
        ConstantItem dao = ModelConvertUtil.convertConstantItemVoToConstantItem(vo);
        int count = constantItemMapper.insert(dao);
        return ReturnResponse.success(count);
    }

    @Override
    public ReturnResponse delete(Long id) {
        boolean isExist = verifyDbExistById(id);
        if (!isExist) {
            return ReturnResponse.fail("The data does not exist in the database.");
        }
        ConstantItem constantItem = constantItemMapper.selectById(id);
        constantItem.setIsDeleted(new Date());
        int count = constantItemMapper.updateById(constantItem);
        return ReturnResponse.success(count);
    }

    @Override
    public ReturnResponse update(ConstantItemVo vo) {
        boolean isExist = verifyDbExistById(Long.valueOf(vo.getId()));
        if (!isExist) {
            return ReturnResponse.fail("The data does not exist in the database.");
        }
        ConstantItem old = constantItemMapper.selectById(vo.getId());
        ModelConvertUtil.fillConstantItemFromConstantItemVo(old, vo);
        int count = constantItemMapper.updateById(old);
        return ReturnResponse.success(count);
    }

    @Override
    public ReturnResponse<List<ConstantItemVo>> selectList(ConstantItemQueryReq req) {
        QueryWrapper<ConstantItem> wrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(req.getConstantKey())) {
            wrapper.eq(ConstantItem.COLUMN.CONSTANT_KEY, req.getConstantKey());
        }
        if (!StringUtils.isEmpty(req.getItemKey())) {
            wrapper.like(ConstantItem.COLUMN.ITEM_KEY, req.getItemKey());
        }
        if (!StringUtils.isEmpty(req.getItemName())) {
            wrapper.like(ConstantItem.COLUMN.ITEM_NAME, req.getItemName());
        }
        if (!StringUtils.isEmpty(req.getDescription())) {
            wrapper.like(ConstantItem.COLUMN.DESCRIPTION, req.getDescription());
        }
        wrapper.isNull(ConstantItem.COLUMN.IS_DELETED);
        List<ConstantItem> list = constantItemMapper.selectList(wrapper);
        List<ConstantItemVo> resultList = list.stream()
                .map(ModelConvertUtil::convertConstantItemToConstantItemVo)
                .collect(Collectors.toList());
        return new ReturnResponse<>(resultList);
    }

    @Override
    public ConstantItem getConstantItemByItemKey(String constantKey, String itemKey) {
        QueryWrapper<ConstantItem> wrapper = new QueryWrapper<>();
        wrapper.eq(ConstantItem.COLUMN.CONSTANT_KEY, constantKey);
        wrapper.eq(ConstantItem.COLUMN.ITEM_KEY, itemKey);
        wrapper.isNull(ConstantItem.COLUMN.IS_DELETED);
        List<ConstantItem> list = constantItemMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(list) || list.size() != 1) {
            throw new RuntimeException("The data does not exist in the database.");
        }
        return list.get(0);
    }

    @Override
    public List<ConstantItem> getConstantItemByEnumConstantKey(String constantKey) {
        QueryWrapper<ConstantItem> wrapper = new QueryWrapper<>();
        wrapper.eq(ConstantItem.COLUMN.CONSTANT_KEY, constantKey);
        wrapper.isNull(ConstantItem.COLUMN.IS_DELETED);
        return constantItemMapper.selectList(wrapper);
    }

    @Override
    public ReturnResponse<List<ConstantItemVo>> selectListByConstantKey(String constantKey) {
        ConstantItemQueryReq req = new ConstantItemQueryReq();
        req.setConstantKey(constantKey);
        return selectList(req);
    }

    /**
     * 校验数据库是否存在该记录
     * @param id
     * @return
     */
    private boolean verifyDbExistById(Long id) {
        QueryWrapper<ConstantItem> wrapper = new QueryWrapper<>();
        wrapper.eq(ConstantItem.COLUMN.ID, id);
        wrapper.isNull(ConstantItem.COLUMN.IS_DELETED);
        Long count = constantItemMapper.selectCount(wrapper);
        return count == 1;
    }

    /**
     * 校验数据库唯一性
     * @param vo
     * @return
     */
    private boolean verifyDbUnique(ConstantItemVo vo) {
        QueryWrapper<ConstantItem> wrapper = new QueryWrapper<>();
        wrapper.eq(ConstantItem.COLUMN.CONSTANT_KEY, vo.getConstantKey());
        wrapper.eq(ConstantItem.COLUMN.ITEM_KEY, vo.getItemKey());
        wrapper.isNull(ConstantItem.COLUMN.IS_DELETED);
        Long count = constantItemMapper.selectCount(wrapper);
        return count == 0;
    }
}
